package com.hnas.sys.service.upload;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.commons.lang.StringUtils;
//import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;

import com.hnas.core.exception.CommonException;
import com.hnas.core.exception.EntityNotFoundException;
import com.hnas.core.util.DateUtil;
import com.hnas.core.util.ExcelReader;
import com.hnas.sys.core.util.InjectKeyCheckUtils;
import com.hnas.sys.dao.AttachmentDAO;
import com.hnas.sys.exception.ValidationCodeException;
import com.hnas.sys.orm.Attachment;
import com.hnas.sys.service.upload.dto.DTOAttachment;
import com.hnas.sys.service.upload.mapper.AttachmentMapper;

@Component("uploadService")
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class UploadServiceImpl implements UploadService {
	@Value(value = "#{component['upload.fileDest']}")
	private String fileDest = "uploadFiles";
//	@Value(value = "#{component['upload.drive']}")
	private String drive = "F";
//	@Value(value = "#{component['upload.maxSize']}")
	private int maxSize = 2 * 1024 * 1024; // 2M
	@Value(value = "#{component['upload.allowContentTypes']}")
	private String allowContentTypes = "application/msword, image/jpeg, image/gif, image/bmp, application/vnd.ms-excel, application/x-xls, application/vnd.ms-powerpoint, application/x-ppt"
			+ "application/x-jpg, application/x-shockwave-flash, image/png, application/x-png, image/pjpeg, text/plain, image/x-png, application/pdf, application/x-zip-compressed, message/rfc822, application/vnd.openxmlformats-officedocument.wordprocessingml.document"; // ,
	// application/octet-stream
//	private int fileIndex = 0;
	
	@Autowired
	private AttachmentDAO attachmentDAO;

	/**
	 * @return c
	 * @throws EntityNotFoundException 
	 */
//	private int getFileIndex() {
//		fileIndex++;
//
//		if (fileIndex >= 100) {
//			fileIndex = 1;
//		}
//
//		return fileIndex;
//	}

	public DTOAttachment getAttchment(long id,int authCode) throws EntityNotFoundException,ValidationCodeException{
		Attachment at  = this.attachmentDAO.find(id);
		if (null==at){
			throw new EntityNotFoundException("");
		}
		if (at.getAuthCode()!=authCode){
			throw new ValidationCodeException("");
		}
		return AttachmentMapper.getInstance().mapToValue(at);
	}
	
	public DTOAttachment saveFile(String s, String prefix, String relativePath) throws IOException {
		Attachment at = new Attachment();
		at.setPostfix(prefix);
		at.setSize(s.length());
		at.setContentType(prefix);
		at.setAuthCode((int) (Math.random() * 1000000));
		this.attachmentDAO.persist(at);
		String pre = "0000" + at.getId();
		pre = pre.substring(pre.length() - 4);
		String fileName = DateUtil.dateToString(new Date(), "yyyyMMddHHmmss")
				+ pre + "." + prefix;
		String spliter = "\\";
		if (this.fileDest.indexOf("/") >= 0) {
			spliter = "/";
		}
		if (StringUtils.isNotEmpty(relativePath)){
			at.setFileName(relativePath + spliter
					+ fileName);
		}else{
			at.setFileName(fileName);
		}
		
		at.setUserFileName(fileName);
		this.attachmentDAO.merge(at);
	
		FileCopyUtils.copy(s.getBytes("UTF-8"), new File(this.fileDest + spliter 
				+ at.getFileName()));

		return AttachmentMapper.getInstance().mapToValue(at);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.hna.adt.service.basic.UploadService#uploadFile(org.springframework
	 * .web.multipart.MultipartFile)
	 */
	public DTOAttachment uploadFile(MultipartFile file) throws CommonException {
		// TODO Auto-generated method stub
		if (file != null && !StringUtils.isEmpty(file.getOriginalFilename())) {
			// String fileName = file.getOriginalFilename();
			try {
				String contentType = file.getContentType();
				if (allowContentTypes.indexOf(contentType) < 0) {
					throw new CommonException("文件格式不允许上传！" + contentType);
				}
				if (file.getSize() > (this.maxSize)) {
					throw new CommonException("上传文件大小超过限制。");
				}
				String userFileName = file.getOriginalFilename();
				int n = userFileName.lastIndexOf(".");
				String fileExt = "";
				if (n >= 0) {
					fileExt = userFileName.substring(n);
				}
				 if (InjectKeyCheckUtils.hasInjectionKey(userFileName,false)){
                	 throw new CommonException("文件名不被允许！");
                  }
					Attachment at = new Attachment();
					at.setUserFileName(file.getOriginalFilename());
					at.setPostfix(fileExt);				
					at.setSize(file.getSize());
					at.setContentType(file.getContentType());
					at.setAuthCode((int) (Math.random()*1000000));
					this.attachmentDAO.persist(at);
					String pre = "000"+at.getId();
					pre = pre.substring(pre.length()-3);
				String fileName = DateUtil.dateToString(new Date(),
						"yyyyMMddHHmmss") + pre + fileExt;				
				at.setFileName(fileName);
				String spliter = "\\";
				if (this.fileDest.indexOf("/")>=0){
					spliter = "/";
				}
				at.setRealPathName(this.fileDest + spliter + fileName);
				this.attachmentDAO.merge(at);				
				FileCopyUtils.copy(file.getBytes(), new File(at.getRealPathName()));
				
				
				return AttachmentMapper.getInstance().mapToValue(at);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				// e.printStackTrace();
				throw new CommonException("上传附件出错：" + e.getMessage() + "/"
						+ file.getOriginalFilename());
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.hna.adt.service.basic.UploadService#downLoadFile(java.lang.String,
	 * java.lang.String, java.io.OutputStream)
	 */
	public void downLoadFile(String uri, OutputStream out)
			throws CommonException{
		// TODO Auto-generated method stub
		String spliter = "\\";
		if (this.fileDest.indexOf("/")>=0){
			spliter = "/";
		}
		String path =  this.fileDest + spliter;

		int index = uri.lastIndexOf("/"); //

		if (index >= 0) {
			uri = uri.substring(index + 1);
		}

		File f = new File(path + uri);

		if (!f.exists()) {

			throw new CommonException(" 指定文件不存在！ ");

		}
		// 取本地文件的大小
		InputStream br = null;

		// 取本地文件的大小
		String fileSize = "0";

		InputStream is = null;
		try {
			is = new FileInputStream(f);
			br = new BufferedInputStream(is);

			byte[] buf = new byte[1024];
			int len = 0; // rdbyte.length;
			fileSize = String.valueOf(len);
			out.flush();

			while ((len = br.read(buf)) > 0)
				out.write(buf, 0, len);

			out.flush();
		} catch (Exception e) {
			// Logger.getLogger(this.getClass().toString()).error(e.getMessage());
			// Logger.getLogger(this.getClass().toString()).info(e.getMessage(),
			// e);
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
//					e.printStackTrace();
				}
			}

			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
//					e.printStackTrace();
				}
			}
			if (null!=is)
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
//					e.printStackTrace();
				}
		}
	}

	public String getFileDest() {
		return fileDest;
	}

	public void setFileDest(String fileDest) {
		this.fileDest = fileDest;
	}

	public String getDrive() {
		return drive;
	}

	public void setDrive(String drive) {
		this.drive = drive;
	}

	public int getMaxSize() {
		return maxSize;
	}

	public void setMaxSize(int maxSize) {
		this.maxSize = maxSize;
	}

	public String getAllowContentTypes() {
		return allowContentTypes;
	}

	public void setAllowContentTypes(String allowContentTypes) {
		this.allowContentTypes = allowContentTypes;
	}
	


	public String getFileContent(String uri) throws SAXException, IOException, ParserConfigurationException, TransformerException, CommonException {
		// TODO Auto-generated method stub
//		File file = new File("G:\\Workspace\\trip\\testAV_Rs2.xml");
		String spliter = "\\";
		if (this.fileDest.indexOf("/")>=0){
			spliter = "/";
		}
		String path =  this.fileDest + spliter;

//		int index = uri.lastIndexOf("/"); //

//		if (index >= 0) {
//			uri = uri.substring(index + 1);
//		}

		File file = new File(path + uri);

		if (!file.exists()) {

			throw new CommonException(" 指定文件不存在！ ");

		}
		byte[] bytes = FileCopyUtils.copyToByteArray(file);
//		Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
//		TransformerFactory tf = TransformerFactory.newInstance();
//		Transformer t = tf.newTransformer();
//		t.setOutputProperty("encoding", "UTF-8");
//		ByteArrayOutputStream bos = new ByteArrayOutputStream();
//		t.transform(new DOMSource(doc), new StreamResult(bos));
		String xmlStr = new String(bytes,"UTF-8");//bos.toString();
		return xmlStr;
	}

//	public void setFileIndex(int fileIndex) {
//		this.fileIndex = fileIndex;
//	}//
	@Value(value = "#{component['order.x.notifyEmail.excel.relativePath']}")
	private String copyExcelPath="excel";
	public long copyExcel(long fromFile, Object copyValue){
		Attachment vo = this.attachmentDAO.find(fromFile);
		String sourceFile = vo.getRealPathName();
		ExcelReader rd = new ExcelReader(sourceFile);
		rd.replaceValue(copyValue);
		Attachment at = new Attachment();
		at.setPostfix(vo.getPostfix());
//		at.setSize(s.length());
		at.setContentType(vo.getContentType());
		at.setAuthCode((int) (Math.random() * 1000000));
		this.attachmentDAO.persist(at);
		String pre = "0000" + at.getId();
		pre = pre.substring(pre.length() - 4);
		String fileName = DateUtil.dateToString(new Date(), "yyyyMMddHHmmss")
				+ pre + "." + at.getPostfix();
		String spliter = "\\";
		if (this.fileDest.indexOf("/") >= 0) {
			spliter = "/";
		}
		if (StringUtils.isNotEmpty(copyExcelPath)){
			at.setFileName(copyExcelPath + spliter
					+ fileName);
		}else{
			at.setFileName(fileName);
		}		
		at.setUserFileName(fileName);
		at.setRealPathName(this.fileDest + spliter 
				+ at.getFileName());
		long fileSize = rd.outputSheet(at.getRealPathName());
		at.setSize(fileSize);
		this.attachmentDAO.merge(at);
	
//		FileCopyUtils.copy(s.getBytes("UTF-8"), new File(this.fileDest + spliter 
//				+ at.getFileName()));
		return at.getId();
	}
}
